package com.test.lucene.index;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.StaleReaderException;
import org.apache.lucene.store.LockObtainFailedException;

import com.subshell.lucene.indexaccess.ILuceneIndexAccessor;
import com.test.lucene.LuceneException;
import com.test.lucene.LuceneRetryException;

/**
 * Delete a document from the Lucene repository.
 * 
 * @author Patrick Kimber
 * 
 */
final class IndexDelete {

    /** The logger. */
    private final Log logger = LogFactory.getLog(IndexDelete.class);

    /**
     * Delete the document. Retry if we get a locking exception.
     * 
     * @param indexAccessor
     *            The Lucene index accessor.
     * @param documentNumber
     *            the document to delete.
     * @throws LuceneException
     *             if cannot delete the document from the index.
     */
    public void delete(final ILuceneIndexAccessor indexAccessor,
            final int documentNumber) throws LuceneException {
        logger.debug("delete(," + documentNumber + ")");
        RetryHandler handler = new RetryHandler(this.getClass().getName());
        Exception thrown;
        do {
            try {
                thrown = null;
                deleteDocument(indexAccessor, documentNumber);
            } catch (LuceneRetryException e) {
                thrown = e;
            }
        } while (handler.retry(thrown));
    }

    /**
     * Function will delete the specified document from the index.
     * 
     * @param indexAccessor
     *            The Lucene index accessor.
     * @param documentNumber
     *            the document to delete
     * @throws LuceneException
     *             if cannot delete document.
     */
    void deleteDocument(final ILuceneIndexAccessor indexAccessor,
            final int documentNumber) throws LuceneException {
        logger.info("deleteDocument(," + documentNumber + ")");
        boolean write = true;
        IndexReader reader = null;
        try {
            reader = indexAccessor.getReader(write);
            System.out.println("DEL: " + documentNumber + " vs " + reader.maxDoc());
            reader.deleteDocument(documentNumber);
        } catch (ArrayIndexOutOfBoundsException e) {
            logger.debug("Document number " + documentNumber
                    + " has already been deleted.");
        } catch (LockObtainFailedException e) {
            throw new LuceneRetryException(e);
        } catch (StaleReaderException e) {
            throw new LuceneRetryException(e);
        } catch (IOException e) {
            throw new LuceneException("I/O Error: Cannot delete document.", e);
        } finally {
            indexAccessor.release(reader, write);
        }
    }
}
